using System;
using System.IO;
using System.Threading;

/*
 * Import SMSLibX libraries created with tlbimp (.NET tool)
 */
using VBA;
using SMSLibXImp;


public class SendReceiveAsync
{
    /*
     * PLEASE ENTER YOUR DATA HERE!
     */
    private static GSMModemTypeConstants s_type =
      GSMModemTypeConstants.gsmModemAudiotelIndustrial; // modem type (see SMSLibX Help)
    private static short s_port = 1;                    // serial COM port number
    private static string s_dest = "";                  // phone number for sent message (ex.+393481234567)
    private static string s_body = "Hello World!";      // text for sent message


    /*
     * Represents the GSM modem
     */
    private static SMSModem s_modem = null;


    /*
     * Wait for user pressing [Enter] key
     */
    private static void ReadIn() {
        TextReader sysIn = Console.In;
        sysIn.ReadLine();
    }

    /*
     * Handler for NewStatus Event
     * (raised when the modem changes its status)
     */
    private static void onNewStatus(SMSModemStatusConstants status) {
        Console.WriteLine("<async> MODEM STATUS {0}", status);
    }

    /*
     * Handler for StatusReport Event
     * (raised when a new SMS-SR status report is received by the modem)
     */
    private static void onStatusReport(ref SMSStatusReport statusReport) {
		Console.WriteLine("<async> Status report for msg({0}): {1}", statusReport.MessageRef, statusReport.MessageStatusName);
    }

    /*
     * Handler for MessageReceived Event
     * (raised when a new SMS-MO message is received by the modem)
     */
    private static void onMessageReceived(ref SMSDeliver deliver) {
    	GSMAddress orig = deliver.Originator;
		Console.WriteLine("<async> Received msg from {0} at {1}: '{2}'", orig.ToString, deliver.Timestamp, deliver.Body);
    }

    /*
     * Initialize the modem
     */
    private static void InitModem() {
        // create modem instance
        s_modem = new SMSModem();

        // add event handlers to the modem instance
        __SMSModem_NewStatusEventHandler newStatusEventHndr = new __SMSModem_NewStatusEventHandler(onNewStatus);
        __SMSModem_StatusReportEventHandler statusReportEventHndr = new __SMSModem_StatusReportEventHandler(onStatusReport);
        __SMSModem_MessageReceivedEventHandler msgReceivedEventHndr = new __SMSModem_MessageReceivedEventHandler(onMessageReceived);
        s_modem.NewStatus += newStatusEventHndr;
        s_modem.StatusReport += statusReportEventHndr;
        s_modem.MessageReceived += msgReceivedEventHndr;

        // start logging
        s_modem.LogTrace = true;
    }

    /*
     * Open modem communication
     */
    private static void OpenModemCommunication() {
        string smsc = "";
        short timeout = 60;
        bool unregMode = false;
        SMSModemNotificationConstants notifyMode = SMSModemNotificationConstants.smsNotifyAll;
            // received messages and other events MUST BE NOTIFIED by the modem to this application

        Console.WriteLine("Opening modem communication...");

        s_modem.OpenComm(s_type, s_port, smsc, notifyMode, timeout, unregMode);

        Console.WriteLine("...OK");
    }

    /*
     * Send a message
     */
    private static void SendMessage(string dest, string body, bool statusReportReq) {
        Console.WriteLine("Sending msg to {0}...", dest);

        int refID = s_modem.SendTextMessage(dest, body, statusReportReq);

        Console.WriteLine("...sent msg({0}) to {1}: '{2}'...", refID, dest, body);
    }

    /*
     * Wait for Enter key to be pressed
     */
    private static void WaitEnterKey() {
        Console.WriteLine("Receiving messages [Press Enter to exit]...");

        // Launch a thread to listen input keys...
        Thread sysInMonitor = new Thread(new ThreadStart(ReadIn));
        sysInMonitor.Start();
        while (! sysInMonitor.IsAlive) { }

        while (sysInMonitor.IsAlive) {
            Thread.Sleep(500);
        }
    }

    /*
     * Close modem communication
     */
    private static void CloseModemCommunication() {
        Console.WriteLine("Closing modem communication...");

        s_modem.CloseComm();

        Console.WriteLine("...OK");
    }

    /*
     * Main method
     */
    public static int Main(string[] args) {
        bool statusReportReq = true;
        if (s_dest.Equals("")) {
            Console.WriteLine("WARNING: You must define a valid <dest> phone address");
            return 1;
        }

		try {
	        InitModem();

	        OpenModemCommunication();

			Console.WriteLine("Press [Enter] to send message...");
			ReadIn();
	        SendMessage(s_dest, s_body, statusReportReq);

	        WaitEnterKey();

	        CloseModemCommunication();
	    }
	    catch (Exception e) {
			Console.WriteLine("ERROR: {0}", e.Message);
	    }

        return 0;
    }
}
